<template>
  <div v-if="ready || showCreatorWall" class="desktop-viewer">
    <CreatorWall v-if="showCreatorWall" :creators="creatorList" @to-end="creatorNextPage"></CreatorWall>
    <MediaViewer
      v-else
      v-model="currIndex"
      :items="fetcher.dataList"
      :active="true"
      :ready="true"
      :loading="fetcher.loading"
      :disable-transition="disableTransition"
      @click:avatar="onAvatarClick"
      @click:tag="onTagClick"
      @to-end="fetcher.nextPage"
    ></MediaViewer>
    <HomeHead v-if="atHome && !currTabType" class="head" v-model="homeTab" v-show="!videoFullscreen"></HomeHead>
    <MediaHead v-else class="head" v-model="mediaType.value" :tab-options="mediaOptions" v-show="!videoFullscreen">
    </MediaHead>
    <div class="feature" v-show="!videoFullscreen">
      <div class="toggler pointer" :class="{ expand: viewerExpand }" @click="toggleViewerExpand">
        <Icon size="50" name="toggler"></Icon>
      </div>
      <Link v-if="showUpDown" class="up" :href="prevHref">
        <Icon size="20" @click="addCurrIndex(-1)" name="up"></Icon>
      </Link>
      <Link v-if="showUpDown" class="down" :href="nextHref">
        <Icon size="20" @click="addCurrIndex(1)" name="down"></Icon>
      </Link>
    </div>
  </div>
  <Loading v-else></Loading>
</template>

<script setup>
import { computed, watchEffect } from 'vue'
import { useRoute } from 'vue-router'
import { onKeyStroke, useActiveElement, useThrottleFn } from '@vueuse/core'
import { storeToRefs } from 'pinia'
import { useAppStore } from '@/store/app'
import { useDesktopViewerStore } from '@/store/desktop-viewer'
import { useFullscreenPhotoStore } from '@/store/fullscreen-photo'
import { useFollowStore } from '@/store/home/follow'
import { useNavStore } from '@/store/nav'
import { usePopupDialogStore } from '@/store/popup-dialog'
import Link from '@/components/common/Link.vue'
import Loading from '@/components/common/Loading.vue'
import HomeHead from '@/components/home/Head.vue'
import CreatorWall from '@/components/home/desktop/CreatorWall.vue'
import { MEDIA_TYPE } from '@/constant'
import { TAB_TYPE } from '@/constant/home'
import { VIEWER_TAB_TYPE } from '@/constant/viewer-router'
import MediaViewer from '../MediaViewer.vue'
import MediaHead from './Head.vue'

const nav = useNavStore()
const { homeTab, atHome } = storeToRefs(nav)

const desktopViewerStore = useDesktopViewerStore()
const { ready, currTabType, currentCreator, currentTag, disableTransition, currIndex, fetcher, mediaType } =
  storeToRefs(desktopViewerStore)
const { nextToTagList, updateCreator, backToSelfNav } = desktopViewerStore

const followStore = useFollowStore()
const { noFollowAnyone, creatorList } = storeToRefs(followStore)
const { creatorNextPage } = followStore

const appStore = useAppStore()
const { videoFullscreen, viewerExpand } = storeToRefs(appStore)
const { toggleViewerExpand } = appStore

const fullscreenPhotoStore = useFullscreenPhotoStore()
const { isOpen: isPhotoFullscreen } = storeToRefs(fullscreenPhotoStore)

watchEffect(() => {
  if (ready.value && mediaType.value && currIndex.value >= 0 && fetcher.value?.dataList.length > 0) {
    const id = fetcher.value?.dataList[currIndex.value]?.author?.aff
    if (id) {
      updateCreator(id)
    }
  }
})

const prevHref = computed(hrefComputer(-1))
const nextHref = computed(hrefComputer(1))
function hrefComputer(offset) {
  return () => {
    if (ready.value && mediaType.value && currIndex.value >= 0 && fetcher.value?.dataList.length > 0) {
      const item = fetcher.value?.dataList[currIndex.value + offset]
      if (item) {
        if (item.type === MEDIA_TYPE.VIDEO) {
          return `/@${item.author.username}/video/${item.id}`
        }
        if (item.type === MEDIA_TYPE.PHOTO) {
          return `/@${item.author.username}/photo/${item.id}`
        }
      }
    }
    return '/@'
  }
}

const showCreatorWall = computed(() => atHome.value && homeTab.value === TAB_TYPE.FOLLOW && noFollowAnyone.value)
const showUpDown = computed(() => !showCreatorWall.value)

const mediaOptions = computed(() => {
  if (currTabType.value === VIEWER_TAB_TYPE.VIDEO_PHOTO) {
    return [
      { label: 'info.media.video', value: MEDIA_TYPE.VIDEO },
      { label: 'info.media.photo', value: MEDIA_TYPE.PHOTO },
    ]
  } else if (currTabType.value === VIEWER_TAB_TYPE.CREATOR) {
    return [
      { label: 'info.media.subs', value: MEDIA_TYPE.SUBS },
      { label: 'info.media.shop', value: MEDIA_TYPE.SHOP },
      { label: 'info.media.free', value: MEDIA_TYPE.FREE },
    ]
  } else {
    return []
  }
})

function onAvatarClick(aff) {
  currentCreator.value = aff
  backToSelfNav()
}

function onTagClick(tag) {
  toggleViewerExpand(true)
  currentTag.value = tag
  nextToTagList(tag)
  backToSelfNav()
}

const routes = ['search', 'home', 'creator']
const route = useRoute()
const inMediaRoutes = computed(() => routes.some((r) => route.name.indexOf(r) !== -1))
const activeElement = useActiveElement()
const popupDialogStore = usePopupDialogStore()
const { isOpen: isPopupDialogOpen } = storeToRefs(popupDialogStore)
const isFullSrceen = computed(() => videoFullscreen.value || isPhotoFullscreen.value)

function checkKeyboardLock() {
  if (isPopupDialogOpen.value) return true
  if (!inMediaRoutes.value) return true
  if (isFullSrceen.value) return true
  if (['input', 'textarea'].includes(activeElement.value.tagName.toLowerCase())) return true
  return false
}

const addCurrIndex = useThrottleFn((v) => {
  // 如果是創作者牆或是榜單就禁用滑動
  if (showCreatorWall.value) return

  currIndex.value += v
  if (currIndex.value === fetcher.value.dataList.length - 2) {
    fetcher.value.nextPage()
  }
}, 750)

const moveMediaType = useThrottleFn((delta) => {
  if (atHome.value) {
    homeTab.value = delta > 0 ? TAB_TYPE.FORYOU : TAB_TYPE.FOLLOW
  } else {
    const options = mediaOptions.value
    if (options.length > 0) {
      const currIndex = options.findIndex((e) => e.value === mediaType.value.value)
      if (delta > 0 && currIndex < options.length - 1) {
        mediaType.value.value = options[currIndex + 1].value
      }
      if (delta < 0 && currIndex > 0) {
        mediaType.value.value = options[currIndex - 1].value
      }
    }
  }
}, 300)

onKeyStroke('ArrowDown', (e) => {
  if (checkKeyboardLock()) return
  e.preventDefault()
  addCurrIndex(1)
})
onKeyStroke('ArrowUp', (e) => {
  if (checkKeyboardLock()) return
  e.preventDefault()
  addCurrIndex(-1)
})
onKeyStroke('ArrowRight', (e) => {
  if (checkKeyboardLock()) return
  e.preventDefault()
  moveMediaType(1)
})
onKeyStroke('ArrowLeft', (e) => {
  if (checkKeyboardLock()) return
  e.preventDefault()
  moveMediaType(-1)
})
</script>

<style lang="scss" scoped>
.desktop-viewer {
  width: 100%;
  height: 100%;
  position: relative;

  .head {
    position: absolute;
    top: 0;
  }

  .feature {
    width: 4.8125rem;
    position: absolute;
    top: 3rem;
    right: 0;

    .toggler {
      width: 2.75rem;
      height: 3.0625rem;
      border-radius: 3.125rem 0 0 3.125rem;
      border: 0.125rem solid rgba(215, 215, 215, 0.4);
      border-right: none;
      background: rgba(0, 0, 0, 0.21);
      position: absolute;
      right: 0;
      display: flex;
      justify-content: center;
      align-items: center;

      &.expand .icon {
        transform: none;
      }

      .icon {
        transform: rotate(180deg);
        transition: transform 0.3s;
      }
    }

    .up,
    .down {
      position: absolute;
      right: 0.75rem;
    }

    .up {
      top: 4rem;
    }

    .down {
      top: 5.5rem;
    }
  }
}
</style>
